1-1. Теоритическая информация
Что такое RPG Maker MV / MZ? «Мукер – это мы»(с)
Мейкер условно состоит из 2-х частей – Редактора и Интерпретатора (он же «проект», «игра»).
Редактор, написан на QT и является +- нативными приложением (как я понял). Интерпретатор же представляет собой локальный веб-сервер со встроенным браузером и (относительно) много кода на JavaScript + файлы графики/
музыки. При этом в роли «локального веб-сервера и встроенный браузера» одновременно выступает NW.js. Также есть варианты экспорта «игры» для своего сервера (без браузера и NW.js в комплекте) и для Android (на MV) – но эти возможности лежат вне темы туториала.
Данная информация интересна больше для «плагинописетелей» (что плагинами при желании можно изменить минимум 80% движка, мы все знаем), но нам тоже полезно понимать, что игра на мукере это, по сути, браузерная игра. И что NW.js также включает в себя API Node.js, что позволяет нам работать с файлами операционной системы (читать, писать).
То, что мы кликаем-клацаем в Редакторе, карты-эвенты-скилы, сохраняется в виде JSON-файлов, которые и интерпретирует Интерпретатор. При сильном желании и понимании процесса можно эти файлы править руками, например меняя диалоги, хар-ки оружия, итд. То есть, полностью зная работу Интерпретатора, можно сделать и свой Редактор с преферансом и поэтессами …и отгрести от злых японских юристов.
Все это подводит к мысли, что как таковой мейкер – оболочка для запуска и работы, код JS да JSON-файлы с нашими данными и кнопочки редактора лишь удобная, в основном, над ним надстройка.
Разработчики мейкера написали тысячи срок кода не совсем для красоты (и наших мучений), а предоставляя также некий внутренний «API» – перечень «внутренних» функций и игровых объектов – который, кроме редактора, можем использовать и мы. И именно их код и представляем собой «движок».
Стоит понимать, что кроме API для игры и игрока, есть еще и «служебные» классы, отвечающие за логику сцен, отрисовку графики, проигрывание музыки, работу с файлами сохранений, тот же интерпретатор команд редактора – вот их из игры мы менять не можем (тут вступают в бой плагины…).
То есть, кратко – любая кнопка редактора есть визуализация внутренней скриптовой команды. И писать код в некоторых ситуациях может быть удобнее, чем накликивать десятки эвентов (как минимум это часто быстрее работает).
1-2. Техническая информация
Под технической информацией имеется ввиду то самое «API» мейкера, которое нам («на лопате») предоставили его разрабы. Детальную информацию можно найти в уроках DK, в сторонней документации (ссылки в Предисловии), ну и открыв файлы движка блокнотом.
С практической стороны, среди многих, нас интересуют следующие объекты и классы (а также их свойства и методы):
1) Хранилище переменных - объект $gameVariables
2) Хранилище переключателей - объект $gameSwitches
3) Хранилище локальных переключателей - объект $gameSelfSwitches
4) Объект игровой карты - $gameMap
5) Объект с данными карты - $dataMap
6) Объект эвента (за него отвечает класс Game_Event)
7) Объект игрока $gamePlayer
8) Объект экрана - $gameScreen
9) Статический класс Scene
10) Статический класс AudioManager
После старта игры нам в любой момент как в игре, так и через консоль доступна работа с созданными игровыми объектами – например, в игре включить какой-то переключатель можно командой редактора или скриптовой командой $gameSwitches.setValue(n, true).
Так как в практической части рассматривается использование эвентов на карте, нужно понимать, как соотносится видимая информация в редакторе и итоговая программная реализация в игре, а именно – эвенты разделают информацию в двух объектах, $gameMap и $dataMap.
При этом, при инициализации карты сначала создаются «эвенты» в $dataMap, на основании чего движком уже создается массив эвентов в $gameMap.
Это важно, так как эвенты в $dataMap содержат текст из Примечания эвента и в массиве эвентов нумерация идет по порядку, видимому в редакторе (не с нуля), а в массиве эвентов $gameMap – с нуля и нет инфы из Примечания.
О самой же карте нам важно помнить, что она состоит из клеток, у каждой клетки есть координаты и может быть (или не быть) регион с номером.
О эвентах важно знать, что у них есть свойства _x , _y, _direction и _eventId , отвечающие за координаты на экране, направление движения, Id (то есть номер) эвента, страницы и Примечание; координаты и направление также есть и у объекта игрока. И эти свойства можно менять вручную, перемещая эвент (или игрока) по экрану. Также важно помнить, что локальные переключатели эвентов хранятся не в объектах эвентов, а в объекте $gameSelfSwitches.
Также нужно учитывать, что объект с переменными может хранить любой тип переменной – и текст, и массив, и функцию, и объект – а не только число. Что позволяет нам писать функцию и сохранять ее в переменной, используя своего-рода «распиленный» на куски плагин.
Именно такой подход, сохранение функций в переменных, используется в практических примерах. Абсолютно безболезненно можно вынести это в плагин и вызывать его.
Предпоследнее из теоретической части – нужно помнить, где именно можно вызывать скрипты в процессе игры и есть ли «привязка» к вызывающему скрипт эвенту. Вызывать скрипты можно в:
1) Команде эвента «Скрипт» (вызывает без привязки в эвенту)
2) В Задании маршрута эвента (вызывает с привязкой к эвенту)
3) В Условии (вызывает без привязки к эвенту)
Под «привязкой» подразумевается, что мейкер считает эвенты и «перечнем команд» и «объектами на карте», но не всегда одновременно в контексте вызова скрипта. То есть в Команде «Скрипт» и Условии this не указывает на объект эвента (указывает на объект Интерпретатора), а в Задании маршрута – указывает на объект текущего эвента.
И последнее из теории – пример основных скриптовых команд, что будут применяться в практической части.
Код:
$gameVariables.setValue(1, () => {}); // создание функции внутри переменной мейкера.
let myFunction = $gameVariables.value(1); // получение сохраненной функции.
$gameSwitches.setValue(2, true); // включение переключателя.
$gameSelfSwitches.setValue([$gameMap._mapId, event._eventId, ‘A’], false); // выключение локального переключателя «А» како-то эвента.
$gameMap.events(); // получения массива всех эвентов карты.
$gameMap.eventsXy(2, 3)[0]; // получение первого из эвентов, находящихся по заданным координатам.
$gameMap.event(4); // получение эвента по id (от объекта карты).
$dataMap.events; // получение массива data-эвентов (с Примечанием!).
$dataMap.events[5].note; // получение примечания конкретного эвента.
$gameTemp. reserveCommonEvent(6); // вызов Общего события.
$gameScreen.startShake(7, 7, 15); // тряска экрана.
event._x // получение координаты x какого-то эвента.
$gamePlayer._y = 2 // задание координаты y для игрока.
AudioManager.playSe({ name: 'Buzzer1', volume: 60, pitch: 100, pan: 0 }); // воспроизведение SE-звука.
$gameSystem.onBeforeSave(); DataManager.saveGame(8); // для сохранения в указанный слот (нужны оба метода в такой последовательности).
Социальные закладки